package me.yricky.usbhid

class HidDevice(
    val path:String,
    val vendorId: Short,
    val productId: Short,
    val serialNumber:String,
    val releaseNumber:Short,
    val manufacturerName:String,
    val productName: String,
    val interfaceNumber: Int,
    val busType:Byte,
){
    companion object{
        const val UNKNOWN = 0x0.toByte()
        const val USB = 0x1.toByte()
        const val BLUETOOTH = 0x2.toByte()
        const val I2C = 0x3.toByte()
        const val SPI = 0x4.toByte()
    }

    private var ptr:Long = 0

    private external fun nReadBytes(ptr:Long,ba:ByteArray,timeout:Int)
    private external fun nWriteBytes(ptr:Long,ba:ByteArray)
    private external fun nOpenDevice(path:String):Long
    private external fun nClose(ptr:Long)

    private fun <T> checkOpen(lambda:()->T){
        if (isOpened()){ lambda() }
    }

    fun open() = synchronized(this) { if(ptr == 0L) ptr = nOpenDevice(path) }
    fun close() = synchronized(this) { val tmp = ptr.takeIf { ptr != 0L }; ptr = 0L; tmp?.let{ nClose(it) } }
    fun isOpened() = ptr != 0L
    fun readBytes(ba:ByteArray,timeOut:Int = -1) = if(timeOut > 0){
        synchronized(this){ checkOpen { nReadBytes(ptr,ba,timeOut) } }
    }else{ checkOpen { nReadBytes(ptr,ba,-1) } }
    fun writeBytes(ba:ByteArray) = checkOpen{
        nWriteBytes(ptr,ba)
    }
}